package com.example.demo.domain.exam.condition;

import com.example.demo.annotation.ConditionOperator;
import com.example.demo.domain.CombineClause;
import com.example.demo.domain.SingleClause;
import com.example.demo.enums.Operator;
import com.example.demo.exception.ExceptionUtils;
import com.example.demo.service.Clause;

import java.lang.reflect.Field;
import java.util.Collection;

public class ConditionParser {

    public static Clause parser(Object entity) {
        return entity == null ? null : parser(entity, entity.getClass());
    }

    public static Clause parser(Object entity, Class<?> clazz) {
        return entity == null ? null : parserClause(entity, clazz);
    }

    public static Clause parserClause(Object entity, Class<?> clazz) {
        CombineClause clauses = CombineClause.and();
        Field[] fields = clazz.getDeclaredFields();
        for (Field field : fields) {
            ConditionOperator annotation = field.getAnnotation(ConditionOperator.class);
            if (annotation != null) {
                Operator operator = annotation.operator();
                String name = annotation.name();
                Object value = getFieldValue(field, entity);
                if (value == null) {
                    continue;
                }
                if (Collection.class.isAssignableFrom(field.getType())){
                    Collection<?> values = (Collection<?>) value;
                    clauses.add(new SingleClause(name, operator, values.toArray(new Object[0])));
                } else {
                    clauses.add(new SingleClause(name, operator, value));
                }
            }
        }
        return clauses;
    }

    public static Object getFieldValue(Field field, Object condition) {
        field.setAccessible(true);
        try {
            return field.get(condition);
        } catch (IllegalAccessException e) {
            throw ExceptionUtils.exception("获取 %s 字段值失败", field.getName());
        }
    }

}
